/*
 * ImagenesDAO.java
 *
 * Created on 26 de septiembre de 2006, 17:13
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package com.src.computec.facturacion.precosto.dao;
import com.src.computec.facturacion.base.constantes.ConstantesGenerales;
import static com.src.computec.facturacion.base.constantes.ConstantesGenerales.SCHEMA;
import static com.src.computec.facturacion.base.constantes.ConstantesGenerales.CODIGO_DANE_VACIO;
import static com.src.computec.facturacion.base.constantes.ConstantesGenerales.CODIGO_TIPO_PROVEEDOR_MENSAJERIA;
import com.src.computec.facturacion.precosto.dto.ClienteDto;
import com.src.computec.facturacion.precosto.dto.DetalleOrdenProcesoDto;
import com.src.computec.facturacion.precosto.dto.FacturaCerradaDto;
import com.src.computec.facturacion.precosto.dto.FacturacionOrdenesDto;
import com.src.computec.facturacion.precosto.dto.GestionEnvioDto;
import com.src.computec.facturacion.precosto.dto.OrdenProcesoDto;
import com.src.computec.facturacion.precosto.dto.ProductoDto;
import com.src.computec.facturacion.utilidades.DocumentoComparator;
import com.src.computec.radar.base.dao.GenericDAO;
import com.src.computec.radar.base.dao.exception.DAOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;



/**
 *
 * @author Jose Luis Perea Alvarez
 */
public class PreCostoDAO extends GenericDAO implements BasePreCostoDAO 
{
    ConstantesGenerales constantesGenerales = ConstantesGenerales.getInstance();    
    
    /** Creates a new instance of CargueDAO */
    public PreCostoDAO() {
    }
    
    public List getClientes() throws DAOException 
    {
        List retornoLst = new ArrayList();
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        try 
        {
            con = getConnectionDB2();
            statement = con.prepareStatement("SELECT CODIGO_CLIENTE, RAZON_SOCIAL " +
                                             "FROM " + SCHEMA + ".CLIENTE " +
                                             "ORDER BY RAZON_SOCIAL ASC");
            rs = statement.executeQuery();
            
            while (rs.next()) 
            {
                int indice = 0;
                ClienteDto clienteDto = new ClienteDto();
                clienteDto.setCodigoCliente(rs.getString(++indice));
                clienteDto.setRazonSocial(rs.getString(++indice));
                retornoLst.add(clienteDto);
            }
        } 
        catch (SQLException e) {
            throw new DAOException("PreCostoDAO:getClientes: " + e.toString(), e);
        }
        finally {
            closeConnection(con, statement, rs);
        }
        return retornoLst;
    }
    
    public List getProductosByCliente(ClienteDto dto) throws DAOException 
    {
        List retornoLst = new ArrayList();
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            con = getConnectionDB2();
            statement = con.prepareStatement("SELECT CODIGO_CLIENTE, CODIGO_PRODUCTO, DESCRIPCION_PRODUCTO " +
                                             "FROM " + SCHEMA + ".PRODUCTO " +
                                             "WHERE CODIGO_CLIENTE = ? " +
                                             "ORDER BY DESCRIPCION_PRODUCTO ASC");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoCliente());
            rs = statement.executeQuery();
            
            while (rs.next()) 
            {
                int indice1 = 0;
                ProductoDto productoDto = new ProductoDto();
                productoDto.setCodigoCliente(rs.getString(++indice1));
                productoDto.setCodigoProducto(rs.getString(++indice1));
                productoDto.setDescripcionProducto(rs.getString(++indice1));
                retornoLst.add(productoDto);
            }
        } 
        catch (SQLException e) 
        {
            throw new DAOException("PreCostoDAO:getProductosByCliente: " + e.toString(), e);
        }
        finally 
        {
            closeConnection(con, statement, rs);
        }
        return retornoLst;
    }
    
    public List getOrdenesProcesoByFilter(OrdenProcesoDto dto) throws DAOException 
    {
        List retornoLst = new ArrayList();
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        //ResultSet rs2 = null;
               
        try {
            con = getConnectionDB2();
            
            String query =  "SELECT OP.NUMERO_ORDEN, OP.CODIGO_CLIENTE, C.RAZON_SOCIAL, OP.CODIGO_PRODUCTO, P.DESCRIPCION_PRODUCTO, OP.CICLO, OP.FECHA_PROCESO, OP.NUMERO_FACTURA_COMPUTEC " +
                            "FROM " + SCHEMA + ".ORDEN_PROCESO OP " +
                                "INNER JOIN " + SCHEMA + ".CLIENTE C ON OP.CODIGO_CLIENTE = C.CODIGO_CLIENTE " +
                                "INNER JOIN " + SCHEMA + ".PRODUCTO P ON OP.CODIGO_PRODUCTO = P.CODIGO_PRODUCTO " +
                            "WHERE OP.CODIGO_CLIENTE = ? AND YEAR(OP.FECHA_PROCESO) = ? AND MONTH(OP.FECHA_PROCESO) = ? ";            
            boolean entro = false;
            if(dto.getCodigoProducto() != null && !dto.getCodigoProducto().equals(""))
            {
                query += "AND OP.CODIGO_PRODUCTO = ? ";
                entro = true;
            }
            query += "ORDER BY OP.NUMERO_ORDEN ASC";
            
            statement = con.prepareStatement(query);
                        
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoCliente());
            statement.setObject(++indice, dto.getAno());
            statement.setObject(++indice, dto.getMes());
            if(entro)
            {
                statement.setObject(++indice, dto.getCodigoProducto());
            }            
            rs = statement.executeQuery();
            
            while (rs.next()) 
            {
                int indice1 = 0;
                OrdenProcesoDto ordenProcesoDto = new OrdenProcesoDto();
                ordenProcesoDto.setNumeroOrden(rs.getString(++indice1));
                ordenProcesoDto.setCodigoCliente(rs.getString(++indice1));
                ordenProcesoDto.setRazonSocial(rs.getString(++indice1));
                ordenProcesoDto.setCodigoProducto(rs.getString(++indice1));
                ordenProcesoDto.setDescripcionProducto(rs.getString(++indice1));
                ordenProcesoDto.setCiclo(rs.getString(++indice1));
                ordenProcesoDto.setFechaProceso( ConstantesGenerales.STRING_DATE_FORMAT.format(rs.getDate(++indice1)) );
                ordenProcesoDto.setClosed(rs.getString(++indice1) != null? true: false);
                  
                retornoLst.add(ordenProcesoDto);
            }
        } 
        catch (SQLException e) 
        {
            throw new DAOException("PreCostoDAO:getOrdenesProcesoByFilter: " + e.toString(), e);
        }
        finally 
        {
            closeConnection(con, statement, rs);
        }
        return retornoLst;
    }    
    
    public FacturacionOrdenesDto getFacturacionOrdenesProceso(List ordenesProceso, ClienteDto clienteDto) throws DAOException 
    {
        FacturacionOrdenesDto retornoDto = new FacturacionOrdenesDto();
        
        DetalleOrdenProcesoDto consolidadoOrdenProcesoDto = new DetalleOrdenProcesoDto();
        
        Connection con = null;
        PreparedStatement statement = null;
        PreparedStatement statement2 = null;
        PreparedStatement statement3 = null;
        PreparedStatement statement4 = null;
        PreparedStatement statement5 = null;
        
        ResultSet rs = null;
        ResultSet rs2 = null;
        ResultSet rs3 = null;
        ResultSet rs4 = null;
        ResultSet rs5 = null;
        
        try 
        {
            retornoDto.setPuedeCerrarse(this.puedeCerrarseFactura(ordenesProceso));
            
            con = getConnectionDB2();
            //Numero de envios en alguna gestion especifica (Enumerationeste caso los que estan en proceso, o lo que estan en retenciones)
            statement = con.prepareStatement("SELECT COUNT(CODIGO_BARRAS) FROM " + SCHEMA + ".ENVIO WHERE NUMERO_ORDEN = ? AND CODIGO_ULTIMA_GESTION = ? ");
            
            //Numero de envios con gestion de ya distribuidos, que cruzan con la tabla MUNICIPIO_DESTINO_CLIENTE (ya configurados), pero que no tienen nada que ver con adpostal
            statement2 = con.prepareStatement("SELECT COUNT(E.CODIGO_BARRAS) " +
                                              "FROM " + SCHEMA + ".ENVIO E " +
                                              "INNER JOIN " + SCHEMA + ".MUNICIPIO_DESTINO_CLIENTE MDC ON " +
                                                    "E.CODIGO_CLIENTE = MDC.CODIGO_CLIENTE AND " +                                                    
                                                    "E.CODIGO_MUNICIPIO = MDC.CODIGO_MUNICIPIO AND " +
                                                    "E.CODIGO_CENTROP = MDC.CODIGO_CENTROP AND " + 
                                                    "E.CODIGO_DEPARTAMENTO = MDC.CODIGO_DEPARTAMENTO " +
                                              "WHERE E.NUMERO_ORDEN = ? AND " +
                                                    "E.CODIGO_NODO NOT IN (" + constantesGenerales.IDS_NODOS_DEFAULT + ") AND " +
                                                    "E.CODIGO_ULTIMA_GESTION IN (" + constantesGenerales.IDS_GESTIONES_YA_DISTRIBUIDOS + ") AND " +                                                    
                                                    "MDC.CODIGO_TIPO_DESTINO_CLIENTE = ? ");
            
            //Numero de envios para adpostal Bogota
            statement3 = con.prepareStatement("SELECT COUNT(NUMERO_ORDEN) " +
                                              "FROM " + SCHEMA + ".ENVIO " +
                                              "WHERE NUMERO_ORDEN = ? AND CODIGO_NODO = ? AND " +
                                                    "CODIGO_ULTIMA_GESTION IN (" + constantesGenerales.IDS_GESTIONES_YA_DISTRIBUIDOS + ") AND " +
                                                    "CODIGO_DEPARTAMENTO = ? AND CODIGO_MUNICIPIO = ? AND CODIGO_CENTROP = ? ");
            
            //Numero de envios para adpostal Nacional
            statement4 = con.prepareStatement("SELECT COUNT(NUMERO_ORDEN) " +
                                              "FROM " + SCHEMA + ".ENVIO " +
                                              "WHERE NUMERO_ORDEN = ? AND ( " +
                                                                              "CODIGO_NODO = ? OR ( " +
                                                                                                    "CODIGO_NODO = ? AND NOT ( CODIGO_DEPARTAMENTO = ? AND CODIGO_MUNICIPIO = ? AND CODIGO_CENTROP = ? ) " +
                                                                                                   ") " +
                                                                             ") AND " +
                                                    "CODIGO_ULTIMA_GESTION IN (" + constantesGenerales.IDS_GESTIONES_YA_DISTRIBUIDOS + ") ");
                  
            //Numero de envios No identificados (no configurados en tabla MUNICIPIO_DESTINO_CLIENTE) que no tienen nada que ver con No class, ni Adpostal ni retenciones
            statement5   = con.prepareStatement("SELECT COUNT(T.LLAVE) " +
                                                "FROM " +
                                                "( " +
                                                " SELECT ( (E.CODIGO_DEPARTAMENTO * 1000000) + (E.CODIGO_MUNICIPIO * 1000) + (E.CODIGO_CENTROP) ) AS LLAVE " +
                                                " FROM " + SCHEMA + ".ENVIO E " +
                                                " WHERE E.NUMERO_ORDEN = ? AND E.CODIGO_NODO NOT IN (" + constantesGenerales.IDS_NODOS_DEFAULT + ") AND " +
                                                " E.CODIGO_ULTIMA_GESTION IN (" + constantesGenerales.IDS_GESTIONES_YA_DISTRIBUIDOS + ") " +
                                                ") T " +
                                                "WHERE T.LLAVE NOT IN " +
                                                "( " +
                                                " SELECT ( (MDC.CODIGO_DEPARTAMENTO * 1000000) + (MDC.CODIGO_MUNICIPIO * 1000) + (MDC.CODIGO_CENTROP) ) AS LLAVE2 " +
                                                " FROM " + SCHEMA + ".MUNICIPIO_DESTINO_CLIENTE MDC " +
                                                " WHERE MDC.CODIGO_CLIENTE = ? " +
                                                ") ");
            
            
            
            
            /******************************************************************************************/
            
            GestionEnvioDto gestionEnvioDto = new GestionEnvioDto();
            //Traigo las gestiones de tipo gestion Retencion
            gestionEnvioDto.setCodigoTipoGestion(constantesGenerales.ID_TIPO_GESTION_RETENCIONES);            
            List retencionesLst = this.getGestionesEnvioByTipoGestion(gestionEnvioDto);
            
            //Traigo las gestiones de tipo gestion En Proceso
            gestionEnvioDto.setCodigoTipoGestion(constantesGenerales.ID_TIPO_GESTION_EN_PROCESO);            
            List enProcesoLst = this.getGestionesEnvioByTipoGestion(gestionEnvioDto);
            
            //Traigo los Tipo Destino Cliente a partir del cliente 
            List tiposDestinoLstCliente = this.getTiposDestinoByCliente(clienteDto);
            
            int totalTodosEnviosRetenciones = 0;
            int totalTodosEnviosEnProceso = 0;
            int totalTodosEnviosDistribuidos = 0;
                        
            List detallesOrdenesProcesoDto = new ArrayList();
            
            /////////////////////////////////////////////////////
            /////     Listas gestiones del consolidado       ////
            /////////////////////////////////////////////////////
            List enviosRetencionesConsolidado = new ArrayList();                     
            List enviosEnProcesoConsolidado = new ArrayList(); 
            List enviosDistribuidosConsolidado = new ArrayList();         
            /////////////////////////////////////////////////////
            
            Iterator ordenesProcesoIter = ordenesProceso.iterator();
            while(ordenesProcesoIter.hasNext())
            {
                String numeroOrden = (String)ordenesProcesoIter.next();
                
                DetalleOrdenProcesoDto detalleOrden = new DetalleOrdenProcesoDto();
                detalleOrden.setNumeroOrden(numeroOrden);
                detalleOrden.setCodigoCliente(clienteDto.getCodigoCliente());
                
                List enviosRetenciones = new ArrayList();                     
                List enviosEnProceso = new ArrayList(); 
                List enviosDistribuidos = new ArrayList();           
                
                int totalEnviosRetenciones = 0;
                int totalEnviosEnProceso = 0;      
                int totalEnviosDistribuidos = 0;                          
                
                /////////////////////////////////////////////////////////////////////////////////////
                /////////  Traigo las Retenciones
                Iterator iterRetenciones = retencionesLst.iterator();
                while(iterRetenciones.hasNext())
                {
                    GestionEnvioDto auxGestionRetencionDto = (GestionEnvioDto)iterRetenciones.next();
                    
                    GestionEnvioDto gestionRetencionDto = new GestionEnvioDto();
                    gestionRetencionDto.setCodigoGestion(auxGestionRetencionDto.getCodigoGestion());
                    gestionRetencionDto.setNombreGestion(auxGestionRetencionDto.getNombreGestion());
                    gestionRetencionDto.setCodigoTipoGestion(auxGestionRetencionDto.getCodigoTipoGestion());
                    
                    int indice = 0;                    
                    statement.setObject(++indice, numeroOrden);   
                    statement.setObject(++indice, gestionRetencionDto.getCodigoGestion());
                    rs = statement.executeQuery();            
                    if (rs.next()) 
                    {
                        int indice1 = 0;                   
                        int numeroEnvios = rs.getInt(++indice1);
                        gestionRetencionDto.setNumeroEnvios(numeroEnvios);
                        totalEnviosRetenciones+= numeroEnvios;
                    }
                    enviosRetenciones.add(gestionRetencionDto);
                    
                    if(!enviosRetencionesConsolidado.contains(gestionRetencionDto))
                    {
                        GestionEnvioDto gestionRetencionConsolidado = new GestionEnvioDto();
                        gestionRetencionConsolidado.setCodigoGestion(gestionRetencionDto.getCodigoGestion());
                        gestionRetencionConsolidado.setNombreGestion(gestionRetencionDto.getNombreGestion());
                        gestionRetencionConsolidado.setNumeroEnvios(gestionRetencionDto.getNumeroEnvios());
                        enviosRetencionesConsolidado.add(gestionRetencionConsolidado);
                    }
                    else
                    {
                        int indexObject = enviosRetencionesConsolidado.indexOf(gestionRetencionDto);
                        GestionEnvioDto gestionRetencionConsolidado = (GestionEnvioDto)enviosRetencionesConsolidado.get(indexObject);
                        int numEnviosAcumulados = gestionRetencionConsolidado.getNumeroEnvios() + gestionRetencionDto.getNumeroEnvios();
                        gestionRetencionConsolidado.setNumeroEnvios(numEnviosAcumulados);
                    }
                }
                /////////////////////////////////////////////////////////////////////////////////////
                
                /////////////////////////////////////////////////////////////////////////////////////
                /////////  Traigo los que estan en Proceso
                Iterator iterEnProceso = enProcesoLst.iterator();
                while(iterEnProceso.hasNext())
                {
                    GestionEnvioDto auxGestionEnProcesoDto = (GestionEnvioDto)iterEnProceso.next();
                    
                    GestionEnvioDto gestionEnProcesoDto = new GestionEnvioDto();
                    gestionEnProcesoDto.setCodigoGestion(auxGestionEnProcesoDto.getCodigoGestion());
                    gestionEnProcesoDto.setNombreGestion(auxGestionEnProcesoDto.getNombreGestion());
                    gestionEnProcesoDto.setCodigoTipoGestion(auxGestionEnProcesoDto.getCodigoTipoGestion());
                    
                    int indice = 0;                    
                    statement.setObject(++indice, numeroOrden); 
                    statement.setObject(++indice, gestionEnProcesoDto.getCodigoGestion());
                    rs = statement.executeQuery();            
                    if (rs.next()) 
                    {
                        int indice1 = 0;                   
                        int numeroEnvios = rs.getInt(++indice1);
                        gestionEnProcesoDto.setNumeroEnvios(numeroEnvios);
                        totalEnviosEnProceso+= numeroEnvios;
                    }
                    enviosEnProceso.add(gestionEnProcesoDto);
                    
                    if(!enviosEnProcesoConsolidado.contains(gestionEnProcesoDto))
                    {
                        GestionEnvioDto gestionEnProcesoConsolidado = new GestionEnvioDto();
                        gestionEnProcesoConsolidado.setCodigoGestion(gestionEnProcesoDto.getCodigoGestion());
                        gestionEnProcesoConsolidado.setNombreGestion(gestionEnProcesoDto.getNombreGestion());
                        gestionEnProcesoConsolidado.setNumeroEnvios(gestionEnProcesoDto.getNumeroEnvios());
                        enviosEnProcesoConsolidado.add(gestionEnProcesoConsolidado);
                    }
                    else
                    {
                        int indexObject = enviosEnProcesoConsolidado.indexOf(gestionEnProcesoDto);
                        GestionEnvioDto gestionEnProcesoConsolidado = (GestionEnvioDto)enviosEnProcesoConsolidado.get(indexObject);
                        int numEnviosAcumulados = gestionEnProcesoConsolidado.getNumeroEnvios() + gestionEnProcesoDto.getNumeroEnvios();
                        gestionEnProcesoConsolidado.setNumeroEnvios(numEnviosAcumulados);
                    }
                }
                /////////////////////////////////////////////////////////////////////////////////////
                
                /////////////////////////////////////////////////////////////////////////////////////
                /////////  Traigo los Envios Ya Distribuidos
                Iterator iterYaDistribuidos = tiposDestinoLstCliente.iterator();
                while(iterYaDistribuidos.hasNext())
                {
                    GestionEnvioDto auxGestionYaDistribuidoDto = (GestionEnvioDto)iterYaDistribuidos.next();
                    
                    GestionEnvioDto gestionYaDistribuidoDto = new GestionEnvioDto();
                    gestionYaDistribuidoDto.setCodigoGestion(auxGestionYaDistribuidoDto.getCodigoGestion());
                    gestionYaDistribuidoDto.setNombreGestion(auxGestionYaDistribuidoDto.getNombreGestion());
                    gestionYaDistribuidoDto.setCodigoCliente(auxGestionYaDistribuidoDto.getCodigoCliente());
                    
                    int indice = 0;                     
                    statement2.setObject(++indice, numeroOrden);              
                    statement2.setObject(++indice, gestionYaDistribuidoDto.getCodigoGestion());
                    rs2 = statement2.executeQuery();            
                    if (rs2.next()) 
                    {
                        int indice1 = 0;                   
                        int numeroEnvios = rs2.getInt(++indice1);
                        gestionYaDistribuidoDto.setNumeroEnvios(numeroEnvios);
                        totalEnviosDistribuidos+= numeroEnvios;
                    }
                    enviosDistribuidos.add(gestionYaDistribuidoDto);
                    
                    if(!enviosDistribuidosConsolidado.contains(gestionYaDistribuidoDto))
                    {
                        GestionEnvioDto gestionDistribuidoConsolidado = new GestionEnvioDto();
                        gestionDistribuidoConsolidado.setCodigoGestion(gestionYaDistribuidoDto.getCodigoGestion());
                        gestionDistribuidoConsolidado.setNombreGestion(gestionYaDistribuidoDto.getNombreGestion());
                        gestionDistribuidoConsolidado.setNumeroEnvios(gestionYaDistribuidoDto.getNumeroEnvios());
                        enviosDistribuidosConsolidado.add(gestionDistribuidoConsolidado);
                    }
                    else
                    {
                        int indexObject = enviosDistribuidosConsolidado.indexOf(gestionYaDistribuidoDto);
                        GestionEnvioDto gestionDistribuidoConsolidado = (GestionEnvioDto)enviosDistribuidosConsolidado.get(indexObject);
                        int numEnviosAcumulados = gestionDistribuidoConsolidado.getNumeroEnvios() + gestionYaDistribuidoDto.getNumeroEnvios();
                        gestionDistribuidoConsolidado.setNumeroEnvios(numEnviosAcumulados);
                    }
                }
                /////////////////////////////////////////////////////////////////////////////////////
                
                /////////////////////////////////////////////////////////////////////////////////////
                /////////  Traigo el numero de Adpostal Bogota (Se agrega a la lista de ya distribuidos)
                GestionEnvioDto gestionAdpostalBogotaDto = new GestionEnvioDto();
                gestionAdpostalBogotaDto.setCodigoGestion("AB");
                gestionAdpostalBogotaDto.setNombreGestion("ADPOSTAL BOGOTA");
                int indice = 0;
                statement3.setObject(++indice,numeroOrden);
                statement3.setObject(++indice,constantesGenerales.ID_NODO_APARTADOS_AEREOS);
                statement3.setObject(++indice,constantesGenerales.CODIGO_DEPTO_DISTRITOCAPITAL);
                statement3.setObject(++indice,constantesGenerales.CODIGO_MUNICIPIO_BOGOTA);
                statement3.setObject(++indice,constantesGenerales.CODIGO_CENTROP_BOGOTA);
                rs3 = statement3.executeQuery();
                if(rs3.next()) 
                {
                    int indice1 = 0;                   
                    int numeroEnvios = rs3.getInt(++indice1);
                    gestionAdpostalBogotaDto.setNumeroEnvios(numeroEnvios);
                    totalEnviosDistribuidos+= numeroEnvios;
                } 
                if(gestionAdpostalBogotaDto.getNumeroEnvios() > 0)
                {
                    enviosDistribuidos.add(gestionAdpostalBogotaDto);
                    
                    ///Para la parte del consolidado
                    if(!enviosDistribuidosConsolidado.contains(gestionAdpostalBogotaDto))
                    {
                        GestionEnvioDto gestionDistribuidoConsolidado = new GestionEnvioDto();
                        gestionDistribuidoConsolidado.setCodigoGestion(gestionAdpostalBogotaDto.getCodigoGestion());
                        gestionDistribuidoConsolidado.setNombreGestion(gestionAdpostalBogotaDto.getNombreGestion());
                        gestionDistribuidoConsolidado.setNumeroEnvios(gestionAdpostalBogotaDto.getNumeroEnvios());
                        enviosDistribuidosConsolidado.add(gestionDistribuidoConsolidado);
                    }
                    else
                    {
                        int indexObject = enviosDistribuidosConsolidado.indexOf(gestionAdpostalBogotaDto);
                        GestionEnvioDto gestionDistribuidoConsolidado = (GestionEnvioDto)enviosDistribuidosConsolidado.get(indexObject);
                        int numEnviosAcumulados = gestionDistribuidoConsolidado.getNumeroEnvios() + gestionAdpostalBogotaDto.getNumeroEnvios();
                        gestionDistribuidoConsolidado.setNumeroEnvios(numEnviosAcumulados);
                    }
                }
                /////////////////////////////////////////////////////////////////////////////////////
                
                /////////////////////////////////////////////////////////////////////////////////////
                /////////  Traigo el numero de Adpostal Nacionales (Se agrega a la lista de ya distribuidos)
                GestionEnvioDto gestionAdpostalNacionalDto = new GestionEnvioDto();
                gestionAdpostalNacionalDto.setCodigoGestion("AN");
                gestionAdpostalNacionalDto.setNombreGestion("ADPOSTAL NACIONAL");
                indice = 0;
                statement4.setObject(++indice,numeroOrden);
                statement4.setObject(++indice,constantesGenerales.ID_NODO_NACIONAL);
                statement4.setObject(++indice,constantesGenerales.ID_NODO_APARTADOS_AEREOS);
                statement4.setObject(++indice,constantesGenerales.CODIGO_DEPTO_DISTRITOCAPITAL);
                statement4.setObject(++indice,constantesGenerales.CODIGO_MUNICIPIO_BOGOTA);
                statement4.setObject(++indice,constantesGenerales.CODIGO_CENTROP_BOGOTA);
                rs4 = statement4.executeQuery();
                if(rs4.next()) 
                {
                    int indice1 = 0;                   
                    int numeroEnvios = rs4.getInt(++indice1);
                    gestionAdpostalNacionalDto.setNumeroEnvios(numeroEnvios);
                    totalEnviosDistribuidos+= numeroEnvios;
                } 
                if(gestionAdpostalNacionalDto.getNumeroEnvios() > 0)
                {
                    enviosDistribuidos.add(gestionAdpostalNacionalDto);
                    
                    ///Para la parte del consolidado
                    if(!enviosDistribuidosConsolidado.contains(gestionAdpostalNacionalDto))
                    {
                        GestionEnvioDto gestionDistribuidoConsolidado = new GestionEnvioDto();
                        gestionDistribuidoConsolidado.setCodigoGestion(gestionAdpostalNacionalDto.getCodigoGestion());
                        gestionDistribuidoConsolidado.setNombreGestion(gestionAdpostalNacionalDto.getNombreGestion());
                        gestionDistribuidoConsolidado.setNumeroEnvios(gestionAdpostalNacionalDto.getNumeroEnvios());
                        enviosDistribuidosConsolidado.add(gestionDistribuidoConsolidado);
                    }
                    else
                    {
                        int indexObject = enviosDistribuidosConsolidado.indexOf(gestionAdpostalNacionalDto);
                        GestionEnvioDto gestionDistribuidoConsolidado = (GestionEnvioDto)enviosDistribuidosConsolidado.get(indexObject);
                        int numEnviosAcumulados = gestionDistribuidoConsolidado.getNumeroEnvios() + gestionAdpostalNacionalDto.getNumeroEnvios();
                        gestionDistribuidoConsolidado.setNumeroEnvios(numEnviosAcumulados);
                    }
                }
                /////////////////////////////////////////////////////////////////////////////////////                
                               
                /////////////////////////////////////////////////////////////////////////////////////
                /////////  Traigo el numero de NoIdentificados (Se agrega a la lista de ya distribuidos)
                GestionEnvioDto gestionNoIdentificadosDto = new GestionEnvioDto();
                gestionNoIdentificadosDto.setCodigoGestion("NI");
                gestionNoIdentificadosDto.setNombreGestion("NO IDENTIFICADOS");
                
                indice = 0;
                statement5.setObject(++indice,numeroOrden);
                statement5.setObject(++indice,clienteDto.getCodigoCliente());
                rs5 = statement5.executeQuery();
                if(rs5.next()) 
                {
                    int indice1 = 0;                   
                    int numeroEnvios = rs5.getInt(++indice1);
                    gestionNoIdentificadosDto.setNumeroEnvios(numeroEnvios);
                    totalEnviosDistribuidos+= numeroEnvios;
                } 
                if(gestionNoIdentificadosDto.getNumeroEnvios() > 0)
                {
                    enviosDistribuidos.add(gestionNoIdentificadosDto);
                    
                    ///Para la parte del consolidado
                    if(!enviosDistribuidosConsolidado.contains(gestionNoIdentificadosDto))
                    {
                        GestionEnvioDto gestionDistribuidoConsolidado = new GestionEnvioDto();
                        gestionDistribuidoConsolidado.setCodigoGestion(gestionNoIdentificadosDto.getCodigoGestion());
                        gestionDistribuidoConsolidado.setNombreGestion(gestionNoIdentificadosDto.getNombreGestion());
                        gestionDistribuidoConsolidado.setNumeroEnvios(gestionNoIdentificadosDto.getNumeroEnvios());
                        enviosDistribuidosConsolidado.add(gestionDistribuidoConsolidado);
                    }
                    else
                    {
                        int indexObject = enviosDistribuidosConsolidado.indexOf(gestionNoIdentificadosDto);
                        GestionEnvioDto gestionDistribuidoConsolidado = (GestionEnvioDto)enviosDistribuidosConsolidado.get(indexObject);
                        int numEnviosAcumulados = gestionDistribuidoConsolidado.getNumeroEnvios() + gestionNoIdentificadosDto.getNumeroEnvios();
                        gestionDistribuidoConsolidado.setNumeroEnvios(numEnviosAcumulados);
                    }
                }
                
                /////////////////////////////////////////////////////////////////////////////////////
                /////////////////////////////////////////////////////////////////////////////////////
                
                /////////////////////////////////////////////////////////////////////////////////////
                //////////    Hago el set de los totales de cada orden proceso
                detalleOrden.setTotalEnviosRetenciones(totalEnviosRetenciones);                
                detalleOrden.setTotalEnviosEnProceso(totalEnviosEnProceso);
                detalleOrden.setTotalEnviosDistribuidos(totalEnviosDistribuidos);
                
                ///////////////////////////////////////////////////////////////////////////////////////
                //////////   Hago el set de las listas que que contienen las cantidades de cada gestion 
                detalleOrden.setEnviosRetenciones(enviosRetenciones);
                detalleOrden.setEnviosEnProceso(enviosEnProceso);
                detalleOrden.setEnviosDistribuidos(enviosDistribuidos);
                
                detallesOrdenesProcesoDto.add(detalleOrden);
                
                totalTodosEnviosRetenciones+= totalEnviosRetenciones;
                totalTodosEnviosEnProceso+= totalEnviosEnProceso;
                totalTodosEnviosDistribuidos+= totalEnviosDistribuidos;
            }
            /////////////////////////////////////////////////////////////////////////////////////
            //////////    Hago el set de los totales de todas las ordenes de proceso
            retornoDto.setTotalTodosEnviosRetenciones(totalTodosEnviosRetenciones);            
            retornoDto.setTotalTodosEnviosEnProceso(totalTodosEnviosEnProceso);
            retornoDto.setTotalTodosEnviosDistribuidos(totalTodosEnviosDistribuidos);
            
            retornoDto.setDetallesOrdenesProcesoDto(detallesOrdenesProcesoDto); 
            
            /////////////////////////////////////////////////////////////////////////////////////
            ///////////             SET Datos del Consolidado                   ///////////////// 
            consolidadoOrdenProcesoDto.setEnviosRetenciones(enviosRetencionesConsolidado);
            consolidadoOrdenProcesoDto.setEnviosEnProceso(enviosEnProcesoConsolidado);
            consolidadoOrdenProcesoDto.setEnviosDistribuidos(enviosDistribuidosConsolidado);
            
            List consolidadoOrdenProcesoLst = new ArrayList();
            consolidadoOrdenProcesoLst.add(consolidadoOrdenProcesoDto);
            retornoDto.setConsolidadoOrdenProceso(consolidadoOrdenProcesoLst);
            
        } 
        catch (SQLException e) 
        {
            throw new DAOException("PreCostoDAO:ordenesProcesoFacturadas: " + e.toString(), e);
        }
        finally 
        {
            closeConnection(statement5, rs5);
            closeConnection(statement4, rs4);
            closeConnection(statement3, rs3);
            closeConnection(statement2, rs2);
            closeConnection(con, statement, rs);
        }
        return retornoDto;
    }
    
    private List getGestionesEnvioByTipoGestion(GestionEnvioDto dto) throws DAOException 
    {
        List retornoLst = new ArrayList();
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            con = getConnectionDB2();
            statement = con.prepareStatement("SELECT CODIGO_GESTION, NOMBRE_GESTION, CODIGO_TIPO_GESTION " +
                                             "FROM " + SCHEMA + ".GESTION_ENVIO " +
                                             "WHERE CODIGO_TIPO_GESTION = ? " +
                                             "ORDER BY NOMBRE_GESTION");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoTipoGestion());
            rs = statement.executeQuery();
            
            while (rs.next()) 
            {
                int indice1 = 0;
                GestionEnvioDto gestionEnvioDto = new GestionEnvioDto();
                gestionEnvioDto.setCodigoGestion(rs.getString(++indice1));
                gestionEnvioDto.setNombreGestion(rs.getString(++indice1));
                gestionEnvioDto.setCodigoTipoGestion(rs.getString(++indice1));
                retornoLst.add(gestionEnvioDto);
            }
        } 
        catch (SQLException e) 
        {
            throw new DAOException("PreCostoDAO:getGestionesEnvioByTipoGestion: " + e.toString(), e);
        }
        finally 
        {            
            closeConnection(con, statement, rs);
        }
        return retornoLst;
    }
    
    private List getTiposDestinoByCliente(ClienteDto dto) throws DAOException 
    {
        List retornoLst = new ArrayList();
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            con = getConnectionDB2();
            statement = con.prepareStatement("SELECT CODIGO_CLIENTE, CODIGO_TIPO_DESTINO_CLIENTE, NOMBRE_TIPO_DESTINO_CLIENTE " +
                                             "FROM " + SCHEMA + ".TIPO_DESTINO_CLIENTE " +
                                             "WHERE CODIGO_CLIENTE = ? " +
                                             "ORDER BY NOMBRE_TIPO_DESTINO_CLIENTE ASC");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoCliente());
            rs = statement.executeQuery();
            
            while (rs.next()) 
            {
                int indice1 = 0;
                GestionEnvioDto gestionEnvioDto = new GestionEnvioDto();
                gestionEnvioDto.setCodigoCliente(rs.getString(++indice1));
                gestionEnvioDto.setCodigoGestion(rs.getString(++indice1));
                gestionEnvioDto.setNombreGestion(rs.getString(++indice1));                
                retornoLst.add(gestionEnvioDto);
            }
        } 
        catch (SQLException e) 
        {
            throw new DAOException("PreCostoDAO:getTiposDestinoByCliente: " + e.toString(), e);
        }
        finally 
        {
            closeConnection(con, statement, rs);
        }
        return retornoLst;
    }
    
    private boolean puedeCerrarseFactura(List ordenesProceso) throws DAOException 
    {
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        
        int cantidadOrdenes = ordenesProceso.size();
        
        try 
        {
            String numeroOrdenes = "";
            for(int i = 0; i < cantidadOrdenes;) 
            {
                numeroOrdenes += (String)ordenesProceso.get(i);
                if( ++i < cantidadOrdenes ) 
                {
                    numeroOrdenes += ",";
                }
            }  
            con = getConnectionDB2();
            statement = con.prepareStatement("SELECT COUNT(NUMERO_ORDEN) FROM " + SCHEMA + ".ORDEN_PROCESO WHERE NUMERO_ORDEN IN (" + numeroOrdenes + ") AND NUMERO_FACTURA_COMPUTEC IS NULL AND FECHA_FACTURA_CLIENTE IS NULL");
            
            rs = statement.executeQuery();
            
            if(rs.next()) 
            {
                int indice1 = 0;
                int numeroResultados = rs.getInt(++indice1);
                if(cantidadOrdenes == numeroResultados)
                {
                    return true;
                }
            }            
        } 
        catch (SQLException e) 
        {
            throw new DAOException("PreCostoDAO:puedeCerrarseFactura: " + e.toString(), e);
        }
        finally 
        {
            closeConnection(con, statement, rs);
        }
        return false;
    }
    
    public void cerrarFactura(FacturaCerradaDto facturaCerradaDto) throws DAOException
    {
        Connection con = null;
        PreparedStatement statement = null;
        
        List ordenesProceso = facturaCerradaDto.getOrdenesProceso();
        int cantidadOrdenes = ordenesProceso.size();
        
        try 
        {
            String numeroOrdenes = "";
            for(int i = 0; i < cantidadOrdenes;) 
            {
                numeroOrdenes += (String)ordenesProceso.get(i);
                if( ++i < cantidadOrdenes ) 
                {
                    numeroOrdenes += ",";
                }
            }  
            con = getConnectionDB2();
            statement = con.prepareStatement("UPDATE " + SCHEMA + ".ORDEN_PROCESO SET NUMERO_FACTURA_COMPUTEC = ?, FECHA_FACTURA_CLIENTE = ? WHERE NUMERO_ORDEN IN (" + numeroOrdenes + ") ");
            
            int indice = 0;
            statement.setObject(++indice, facturaCerradaDto.getNumeroFactura());
            statement.setObject(++indice, new Timestamp(facturaCerradaDto.getFechaFactura().getTime()));
            statement.executeUpdate();
        } 
        catch (SQLException e) 
        {
            throw new DAOException("PreCostoDAO:cerrarFactura: " + e.toString(), e);
        }
        finally 
        {
            closeConnection(con, statement);
        }        
    }
    
    public List getDocumentosComparator(List pListOrdenesProceso) throws DAOException{
	Connection con = null;
        PreparedStatement statement = null;	
        
        ResultSet rs = null;
	ArrayList listDto_=new ArrayList();
	
   
        int cantidadOrdenes = pListOrdenesProceso.size();
        
        try 
        {
            String numeroOrdenes = "";
            for(int i = 0; i < cantidadOrdenes;) 
            {
                numeroOrdenes += (String)pListOrdenesProceso.get(i);
                if( ++i < cantidadOrdenes ) 
                {
                    numeroOrdenes += ",";
                }
            }  
            con = getConnectionDB2();
	    
	/*	SELECT DOC.CODIGO_BARRAS,DOC.NUMERO_DOCUMENTO,ENV.NUMERO_ORDEN,ENV.CODIGO_CLIENTE,C.RAZON_SOCIAL,P.DESCRIPCION_PRODUCTO,ENV.FECHA_PROCESO
		FROM PRODRAD.DOCUMENTO DOC 
		INNER JOIN PRODRAD.ENVIO ENV ON ENV.CODIGO_BARRAS=DOC.CODIGO_BARRAS 
		INNER JOIN PRODRAD.CLIENTE C ON ENV.CODIGO_CLIENTE=C.CODIGO_CLIENTE
		INNER JOIN PRODRAD.PRODUCTO P ON P.CODIGO_PRODUCTO=ENV.CODIGO_PRODUCTO
		WHERE ENV.NUMERO_ORDEN=8000*/
		    
	    String query_="SELECT DOC.CODIGO_BARRAS,DOC.NUMERO_DOCUMENTO,ENV.NUMERO_ORDEN,ENV.CODIGO_CLIENTE,C.RAZON_SOCIAL,P.DESCRIPCION_PRODUCTO " +
					    "FROM PRODRAD.DOCUMENTO DOC " +
					    "INNER JOIN PRODRAD.ENVIO ENV ON ENV.CODIGO_BARRAS=DOC.CODIGO_BARRAS " +
					    "INNER JOIN PRODRAD.CLIENTE C ON ENV.CODIGO_CLIENTE=C.CODIGO_CLIENTE " +
					    "INNER JOIN PRODRAD.PRODUCTO P ON P.CODIGO_PRODUCTO=ENV.CODIGO_PRODUCTO " +
					    "WHERE ENV.NUMERO_ORDEN IN ("+numeroOrdenes+")";
	    //System.out.println("QUERY:"+query_);
		    
            statement = con.prepareStatement(query_);
            
            rs = statement.executeQuery();
            
            while(rs.next()) 
            {	
                int indice1 = 0;
                //int numeroResultados = rs.getInt(++indice1);              
		DocumentoComparator cto_=new DocumentoComparator();
		cto_.setCodigoBarras(rs.getString(++indice1));
		cto_.setNumeroDocumento(rs.getString(++indice1));
		cto_.setNumeroOrdenProceso(rs.getString(++indice1));
		cto_.setCodigoCliente(rs.getString(++indice1));
		cto_.setRazonSocialCliente(rs.getString(++indice1));
		cto_.setDescProducto(rs.getString(++indice1));
		listDto_.add(cto_);
            }            
        } 
        catch (SQLException e) 
        {
            throw new DAOException("PreCostoDAO:getDocumentosComparator: " + e.toString(), e);
        }
        finally 
        {
	    
            closeConnection(con, statement, rs);
        }
        
	return listDto_;
    }
    
    
    public void insertMensajeAlerta(String fileName, String ldapUser,String pDescripcion,String pOrigen) throws DAOException {
        Connection con = null;
        PreparedStatement statement = null;
        try {
            con = getConnectionDB2();
            statement = con.prepareStatement("INSERT INTO " + SCHEMA + ".MENSAJE_ALERTA (CODIGO_TIPO_ARCHIVO, CODIGO_RESPONSABLE, DESCRIPCION_MENSAJE_ALERTA, ORIGEN_MENSAJE_ALERTA, PATH_MENSAJE_ALERTA, FECHA_REGISTRO, ESTADO) " +
                                             "VALUES (?, ?, ?, ?, ?, ?, ?)");
            int indice = 0;
            statement.setObject(++indice, ConstantesGenerales.FILE_CODE);
            statement.setObject(++indice, ldapUser);
            statement.setObject(++indice, pDescripcion);
            statement.setObject(++indice, pOrigen);
            statement.setObject(++indice, fileName);
            statement.setTimestamp(++indice, new Timestamp(System.currentTimeMillis()));
            statement.setObject(++indice, ConstantesGenerales.FILE_ACTIVE);
            statement.executeUpdate();
        }
        catch (SQLException e) {
            throw new DAOException("InconsistenciasDAO:insertMensajeAlerta: " + e.toString(), e);
        }
        finally {
            closeConnection(con, statement);
        }
    }
}
